package AppSsl

import (
	"encoding/json"
	"fmt"
	"gitee.com/liumou_site/logger"
	"gitee.com/liumou_site/tencent-cloud-ssl-automatic/module/AppStruct"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
	ssl "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ssl/v20191205"
)

// ApplyCertificate 申请并应用证书到指定域名。
// 参数:
//
//	SecretId: 腾讯云账户的SecretId，用于身份验证。
//	SecretKey: 腾讯云账户的SecretKey，用于身份验证。
//	Domain: 包含申请证书所需域名配置信息的结构体指针。
//	OldCertificateId: 旧证书ID，用于更新证书。
//
// 返回:
//
//	string: 如果操作成功，返回证书ID；
//	error: 如果操作失败，返回错误信息；否则返回nil。
func ApplyCertificate(SecretId, SecretKey string, Domain *AppStruct.DomainConfig, OldCertificateId string) (string, error) {
	// 检查SecretId和SecretKey是否已设置，这是与腾讯云API通信所必需的
	if len(SecretId) <= 3 || len(SecretKey) <= 3 {
		logger.Error("SecretId or SecretKey is empty")
		return "", fmt.Errorf("SecretId or SecretKey is empty")
	}

	// 检查DVAuthMethod是否已设置，这是申请证书所必需的
	if Domain.DVAuthMethod == "" || Domain.DomainName == "" {
		logger.Error("DvAuthMethod is empty")
		return "", fmt.Errorf("DvAuthMethod is empty")
	}

	// 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey
	credential := common.NewCredential(SecretId, SecretKey)

	// 实例化一个client选项，可选的，没有特殊需求可以跳过
	cpf := profile.NewClientProfile()
	cpf.HttpProfile.Endpoint = "ssl.tencentcloudapi.com"

	// 实例化要请求产品的client对象
	client, _ := ssl.NewClient(credential, "", cpf)

	// 实例化一个请求对象
	request := ssl.NewApplyCertificateRequest()

	// 为请求对象设置参数
	request.DvAuthMethod = common.StringPtr(Domain.DVAuthMethod)             // 设置域名验证方法
	request.DomainName = common.StringPtr(Domain.DomainName)                 // 设置申请证书的域名名称
	request.ContactEmail = common.StringPtr(Domain.Email)                    // 设置联系邮箱，用于证书发放和续期通知
	request.CsrEncryptAlgo = common.StringPtr(Domain.CSREncryptAlgo)         // 设置CSR（证书签名请求）的加密算法
	request.CsrKeyParameter = common.StringPtr(Domain.CSRKeyParameter)       // 设置CSR的密钥参数
	request.Alias = common.StringPtr(Domain.Remark)                          // 设置证书的别名或备注
	request.OldCertificateId = common.StringPtr(OldCertificateId)            // 如果是重新颁发或更新证书，设置旧证书ID
	request.DeleteDnsAutoRecord = common.BoolPtr(Domain.DeleteDNSAutoRecord) // 指示是否在验证后删除DNS自动记录

	// 发起申请证书的请求，并处理响应或错误
	response, err := client.ApplyCertificate(request)
	if _, ok := err.(*errors.TencentCloudSDKError); ok {
		logger.Error("An API error has returned: ", err)
		return "", err
	}

	// 输出json格式的字符串回包
	logger.Info(response.ToJsonString())
	logger.Info("Success: ", Domain.DomainName)
	// 解析JSON字符串
	result := Result{}
	err = json.Unmarshal([]byte(response.ToJsonString()), &result)
	if err != nil {
		logger.Error("UnmarshalJSONString error: ", err)
		return "", err
	}
	return result.Response.CertificateID, nil
}
